package com.sig.formes;


import java.util.ArrayList;
import java.util.List;
import android.util.Log;

public class Segment extends Forme{

	public Point debut;
	public Point fin;
	public float epaisseur;
	public float[] color;
	public boolean dessinerBord = false;
	public Polyedre poly;

	//bordures
	public Polyedre border1 = null;
	public Polyedre border2 = null;
	public static float BORDER_WIDTH = 0.02f;
	public static float[] BORDER_COLOR = Forme.gris_fonce ;
	
	////////////////////////:CONSTRUCTEUR://///////////////////////////////////
	public Segment(Point debut,Point fin){
		this.debut = debut;
		this.fin = fin;
		this.epaisseur = 0.03f ;
		color = Forme.rose;
		creer(color);
	}

	public Segment(Point debut,Point fin,float epaisseur){
		this.debut = debut;
		this.fin = fin;
		this.epaisseur = epaisseur;
		creer(color);
	}
	
	public Segment(Point debut,Point fin,float epaisseur,float [] color){
		this.debut = debut;
		this.fin = fin;
		this.color = color;
		this.epaisseur = epaisseur;
		creer(color);
	}
	
	/////////////////////:UTILS://///////////////////////////////////////
	

	public Point segmentIntersect(Segment s,boolean as_seg)
	{

		Point ip;
		float a1;
		float a2;
		float b1;
		float b2;
		float c1;
		float c2;

		Point A = debut;
		Point B = fin;
		Point E = s.debut;
		Point F = s.fin;

		a1= B.y-A.y;
		b1= A.x-B.x;
		c1= B.x*A.y - A.x*B.y;
		a2= F.y-E.y;
		b2= E.x-F.x;
		c2= F.x*E.y - E.x*F.y;

		float denom = a1*b2 - a2*b1;
		if(denom == 0){
			return null;
		}
		ip=new Point();
		ip.x=((b1*c2 - b2*c1)/denom);
		ip.y=((a2*c1 - a1*c2)/denom);

		if(as_seg){
			if(distance(ip,B) > distance(A,B)){
				return null;
			}
			if(distance(ip,A) > distance(A,B)){
				return null;
			}  

			if(distance(ip,F) > distance(E,F)){
				return null;
			}
			if(distance(ip,E) > distance(E,F)){
				return null;
			}
		}
		return ip;
	}

	public static double distance(Point fin,Point p2) {
		double dx=fin.x-p2.x;
		double dy=fin.y-p2.y;
		return Math.sqrt(dx*dx+dy*dy);
	}

	public boolean equals(Segment s)
	{
		return ( ( debut == s.debut && fin == s.fin ) || ( debut == s.fin && fin == s.debut ) );
	}

	public Point getCenter()
	{
		return new Point( debut.x + ( fin.x - debut.x )/2, debut.y + ( fin.y - debut.y ) / 2 );
	}

	public double determinant(Point debut,Point fin,Point p2 )
	{
		return ( ( debut.x-fin.x )*( p2.y - fin.y ) ) - ( ( p2.x-fin.x )*( debut.y-fin.y ) );
	}
	public Point midPoint()
	{
		return new Point( ( debut.x + fin.x ) / 2, ( debut.y + fin.y ) / 2 );
	}

	/////////////////////:CONVERSION://////////////////////////////
	public static com.sig.formes.Segment convert(utils.Segment s, float[] color,float epaisseur)
	{
		Point deb = new Point(s.getDebut().getX(), s.getDebut().getY());
		Point fin = new Point(s.getFin().getX(), s.getFin().getY());;
		
		return new com.sig.formes.Segment(deb,fin,epaisseur,color);
	}
	
	///////////////////:OPENGL://///////////////////////////////////
	
	public void draw(float[] mvpMatrix) {
		if(!cree){
			cree=true;
			creer(mvpMatrix);
		}
		
		super.draw(mvpMatrix);
		poly.draw(mvpMatrix);	
		if(dessinerBord){
			poly.dessinerBordure(mvpMatrix);
		}
		
	}

	public static final float epsylon = 4f;
	private boolean egaliteY(float x, float y){
		if(x == y)
			return true;		
		
		if(y>= x-epsylon && y <= x+epsylon)
			return true;
		
		return false;
	}
	
	public void creer(float[] mvpMatrix){
		List<Point> points = new ArrayList<Point>();
		
			if(egaliteY(this.debut.y,this.fin.y)){
				points.add(new Point(this.debut.x, this.debut.y+epaisseur));
				points.add(new Point(this.fin.x, this.fin.y+epaisseur));
				points.add(new Point(this.fin.x, this.fin.y-epaisseur));
				points.add(new Point(this.debut.x, this.debut.y-epaisseur));		
			}else{
				points.add(new Point(this.debut.x-epaisseur, this.debut.y));
				points.add(new Point(this.debut.x+epaisseur, this.debut.y));
				points.add(new Point(this.fin.x+epaisseur, this.fin.y));
				points.add(new Point(this.fin.x-epaisseur, this.fin.y));
				
			}
		poly = new Polyedre(points, color);
	}

	@Override
	public void recreer(){
		super.recreer();
		poly.recreer();	
	}

	public static List<Segment> pointToList(List<Point>ps){
		List<Segment> segs = new ArrayList<Segment>();
		for(int i = 0 ; i < ps.size() - 1;i++){
			segs.add(new Segment(ps.get(i),ps.get(i+1)));
		}

		if(ps.size() > 2){
			segs.add(new Segment(ps.get(ps.size()-1),ps.get(0)));
		}
		return segs;
	}

	@Override
	public List<Triangle> getTriangles() {
		ArrayList<Triangle> triangles = new ArrayList<Triangle>();
		if(this.poly != null)
		{
			triangles.addAll(this.poly.getTriangles());
		}
		else
		{
			Log.v("sig_layer_segment", "le segment n'a pas de polyedre creer!!");
		}
		return triangles;
	}
	
	
	////////////////////////:GESTION DES BORDURES://////////////////////
	public List<Triangle> getBorder(){
		ArrayList<Triangle> res = new  ArrayList<Triangle>();
		
		if(border1 == null || border2 == null)
		{
			createBorders();
		}
		
		res.addAll(this.border1.getTriangles());
		res.addAll(this.border2.getTriangles());
		
		return res;
	}

	private void createBorders() {
		Point deb1 = new Point(this.debut.getX()+(this.epaisseur),this.debut.getY()+(this.epaisseur));
		Point fin1 = new Point(this.fin.getX()+(this.epaisseur),this.fin.getY()+(this.epaisseur));
		
		Point deb2 = new Point(this.debut.getX()-(this.epaisseur),this.debut.getY()-(this.epaisseur));
		Point fin2 = new Point(this.fin.getX()-(this.epaisseur),this.fin.getY()-(this.epaisseur));
		
		Segment b1 = new Segment(deb1, fin1, BORDER_WIDTH);
		Segment b2 = new Segment(deb2, fin2, BORDER_WIDTH);
		b1.color = BORDER_COLOR;
		b2.color = BORDER_COLOR;
		this.border1 = b1.poly;
		this.border2 = b2.poly;
	}

	public Polyedre getBorder1() {
		if(border1 == null)
			createBorders();
		
		return border1;
		
	}

	public void setBorder1(Polyedre border1) {
		this.border1 = border1;
	}

	public Polyedre getBorder2() {
		if(border2 == null)
			createBorders();
		return border2;
	}

	public void setBorder2(Polyedre border2) {
		this.border2 = border2;
	}
}